package com.ruoyi.job.task;
import java.io.*;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;

public class CrossPlatformBackupManager {

    // 数据库配置
    private static final String DB_HOST = "localhost";
    private static final String DB_PORT = "3306";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "xhc.1949&QW";
    private static final String[] DATABASES = {"ry-cloud", "ry-config", "ry-seata"};
    private static final int KEEP_DAYS = 7;

    /**
     * 执行数据库备份（跨平台）- 主方法
     */
    public static void executeBackup() {
        try {
            // 获取系统信息
            String os = System.getProperty("os.name").toLowerCase();
            boolean isWindows = os.contains("win");

            // 设置备份目录
            String backupDir = isWindows ? "C:\\backup" : "/opt/physical/backup";
            String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

            // 创建备份目录
            File backupDirFile = new File(backupDir);
            if (!backupDirFile.exists()) {
                backupDirFile.mkdirs();
                System.out.println("创建备份目录: " + backupDir);
            }

            // 查找mysqldump路径
            String mysqldumpPath = findMySQLDumpPath(isWindows);
            if (mysqldumpPath == null) {
                System.out.println("错误: 未找到mysqldump命令");
                return;
            }

            System.out.println("=== 开始数据库备份 ===");
            System.out.println("操作系统: " + System.getProperty("os.name"));
            System.out.println("mysqldump路径: " + mysqldumpPath);
            System.out.println("备份目录: " + backupDir);
            System.out.println("目标数据库: " + String.join(", ", DATABASES));

            int successCount = 0;
            int failCount = 0;

            for (String db : DATABASES) {
                String backupFile = backupDir + File.separator + db + "_" + timestamp + ".sql";

                System.out.println("\n备份数据库: " + db);

                if (backupSingleDatabase(mysqldumpPath, db, backupFile, isWindows)) {
                    successCount++;
                    File file = new File(backupFile);
                    if (file.exists() && file.length() > 0) {
                        System.out.println("✓ 备份成功: " + file.getName() + " (" + file.length() + " bytes)");
                    } else {
                        System.out.println("⚠ 备份完成但文件可能为空");
                    }
                } else {
                    failCount++;
                    System.out.println("✗ 备份失败: " + db);
                }
            }

            System.out.println("\n=== 备份完成 ===");
            System.out.println("成功: " + successCount + " 个数据库");
            System.out.println("失败: " + failCount + " 个数据库");

            // 备份完成后清理过期文件
            if (successCount > 0) {
                System.out.println("\n开始清理过期备份文件...");
                cleanOldBackupFiles(backupDir);
            } else {
                System.out.println("\n所有备份都失败，跳过清理操作");
            }

        } catch (Exception e) {
            System.err.println("备份过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 备份单个数据库 - 修复路径空格问题
     */
    private static boolean backupSingleDatabase(String mysqldumpPath, String database,
                                                String backupFile, boolean isWindows) {
        try {
            ProcessBuilder processBuilder = new ProcessBuilder();

            if (isWindows) {
                // Windows: 使用数组方式，避免路径空格问题
                processBuilder.command(
                        "cmd", "/c",
                        "\"" + mysqldumpPath + "\"",  // 整个路径用引号包围
                        "-h", DB_HOST,
                        "-P", DB_PORT,
                        "-u", DB_USER,
                        database,
                        "-r", backupFile  // 输出文件路径不需要引号，ProcessBuilder会处理
                );
            } else {
                // Linux
                processBuilder.command(
                        mysqldumpPath,
                        "-h", DB_HOST,
                        "-P", DB_PORT,
                        "-u", DB_USER,
                        database,
                        "-r", backupFile
                );
            }

            // 设置密码环境变量（安全方式）
            processBuilder.environment().put("MYSQL_PWD", DB_PASSWORD);
            processBuilder.redirectErrorStream(true);

            // 显示实际执行的命令（调试用）
            System.out.println("  执行命令: " + String.join(" ", processBuilder.command()));

            Process process = processBuilder.start();

            // 读取输出信息
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    process.getInputStream(), isWindows ? "GBK" : "UTF-8"));

            StringBuilder output = new StringBuilder();
            String line;
            boolean hasOutput = false;

            while ((line = reader.readLine()) != null) {
                if (!hasOutput) {
                    System.out.println("  输出信息:");
                    hasOutput = true;
                }
                System.out.println("    " + line);
                output.append(line).append("\n");
            }
            reader.close();

            int exitCode = process.waitFor();

            if (exitCode == 0) {
                return true;
            } else {
                System.out.println("  退出码: " + exitCode);
                return false;
            }

        } catch (Exception e) {
            System.err.println("备份数据库 " + database + " 时发生错误: " + e.getMessage());
            return false;
        }
    }

    /**
     * 清理过期备份文件（跨平台）
     */
    public static void cleanOldBackupFiles(String backupDir) {
        File directory = new File(backupDir);
        if (!directory.exists() || !directory.isDirectory()) {
            System.out.println("备份目录不存在: " + backupDir);
            return;
        }

        File[] files = directory.listFiles((dir, name) ->
                name.endsWith(".sql") &&
                        (name.startsWith("ry-cloud_") || name.startsWith("ry-config_") || name.startsWith("ry-seata_"))
        );

        if (files == null || files.length == 0) {
            System.out.println("没有找到需要清理的备份文件");
            return;
        }

        // 计算截止时间
        long cutoffTime = Instant.now().minus(KEEP_DAYS, ChronoUnit.DAYS).toEpochMilli();
        int deletedCount = 0;
        int keptCount = 0;

        System.out.println("保留天数: " + KEEP_DAYS + " 天");
        System.out.println("截止时间: " + new Date(cutoffTime));
        System.out.println("找到备份文件: " + files.length + " 个");

        for (File file : files) {
            if (file.lastModified() < cutoffTime) {
                if (file.delete()) {
                    System.out.println("✓ 已删除过期文件: " + file.getName());
                    deletedCount++;
                } else {
                    System.out.println("✗ 删除失败: " + file.getName());
                }
            } else {
                keptCount++;
            }
        }

        System.out.println("=== 清理完成 ===");
        System.out.println("删除文件: " + deletedCount + " 个");
        System.out.println("保留文件: " + keptCount + " 个");
        System.out.println("总计文件: " + files.length + " 个");
    }

    /**
     * 查找mysqldump路径（跨平台）
     */
    private static String findMySQLDumpPath(boolean isWindows) {
        try {
            // 常见安装路径
            String[] possiblePaths;
            if (isWindows) {
                possiblePaths = new String[]{
                        "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqldump.exe",
                        "C:\\Program Files\\MySQL\\MySQL Server 5.7\\bin\\mysqldump.exe",
                        "mysqldump.exe"  // PATH中的命令
                };
            } else {
                possiblePaths = new String[]{
                        "/usr/bin/mysqldump",
                        "/usr/local/mysql/bin/mysqldump",
                        "/opt/mysql/bin/mysqldump",
                        "mysqldump"  // PATH中的命令
                };
            }

            // 检查常见路径
            for (String path : possiblePaths) {
                File file = new File(path);
                if (file.exists()) {
                    return path;
                }
            }

            // 如果在常见路径中没找到，尝试使用which/where命令查找
            ProcessBuilder pb;
            if (isWindows) {
                pb = new ProcessBuilder("where", "mysqldump.exe");
            } else {
                pb = new ProcessBuilder("which", "mysqldump");
            }

            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String foundPath = reader.readLine();
            reader.close();

            process.waitFor();
            return foundPath;

        } catch (Exception e) {
            System.err.println("查找mysqldump路径时发生错误: " + e.getMessage());
            return null;
        }
    }

    /**
     * 简化的连接测试（仅测试基本连接）
     */
    public static boolean testBasicConnection() {
        try {
            boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");

            // 查找mysql路径
            String mysqlPath = findMySQLDumpPath(isWindows).replace("mysqldump", "mysql");

            ProcessBuilder pb;
            if (isWindows) {
                pb = new ProcessBuilder(
                        "cmd", "/c",
                        "\"" + mysqlPath + "\"",  // 路径用引号包围
                        "-h", DB_HOST, "-P", DB_PORT, "-u", DB_USER,
                        "-e", "SELECT 1 AS connection_test;"
                );
            } else {
                pb = new ProcessBuilder(
                        mysqlPath,
                        "-h", DB_HOST, "-P", DB_PORT, "-u", DB_USER,
                        "-e", "SELECT 1 AS connection_test;"
                );
            }

            pb.environment().put("MYSQL_PWD", DB_PASSWORD);
            pb.redirectErrorStream(true);

            Process process = pb.start();

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    process.getInputStream(), isWindows ? "GBK" : "UTF-8"));

            // 读取输出但不显示（避免干扰）
            while (reader.readLine() != null) {
                // 忽略输出
            }
            reader.close();

            int exitCode = process.waitFor();
            return exitCode == 0;

        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 主方法
     */
    public static void main(String[] args) {
        System.out.println("=== 跨平台MySQL备份管理器 ===");
        System.out.println("目标数据库: " + String.join(", ", DATABASES));

        // 简单测试连接
        System.out.print("测试MySQL基本连接...");
        if (testBasicConnection()) {
            System.out.println(" ✓ 成功");
        } else {
            System.out.println(" ✗ 失败（但继续尝试备份）");
        }

        // 直接执行备份（跳过复杂的数据库存在性检查）
        System.out.println("\n开始执行备份操作...");
        executeBackup();

        System.out.println("\n=== 程序执行完成 ===");
    }
}